package com.seeyon.ctp.rest.resources;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.seeyon.apps.lzmzj.kit.*;
import com.seeyon.apps.lzmzj.manager.MatrimonyFunctionManager;
import com.seeyon.cap4.form.bean.FormBean;
import com.seeyon.cap4.form.bean.FormFieldBean;
import com.seeyon.cap4.form.service.CAP4FormManager;
import com.seeyon.ctp.common.AppContext;
import com.seeyon.ctp.common.authenticate.domain.User;
import com.seeyon.ctp.common.log.CtpLogFactory;
import com.seeyon.ctp.login.UserUtil;
import com.seeyon.ctp.organization.bo.V3xOrgMember;
import com.seeyon.ctp.organization.manager.OrgManager;
import org.apache.commons.logging.Log;
import sun.misc.BASE64Encoder;

import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Path("jssdk")
@Consumes(MediaType.APPLICATION_JSON)
@Produces({MediaType.APPLICATION_JSON})
public class CustomSeeyonBPMResources extends BaseResource {

    private static final Log log = CtpLogFactory.getLog(CustomSeeyonBPMResources.class);

    private String localAddr = AppContext.getRawRequest().getLocalAddr();
    private String port = String.valueOf(AppContext.getRawRequest().getLocalPort());
    private String tokenUrl = "http://" + localAddr + ":" + port + "/seeyon/rest/token";
    private String bpmUrl = "http://" + localAddr + ":" + port + "/seeyon/rest/bpm/process/start";

    private MatrimonyFunctionManager matrimonyFunctionManager = (MatrimonyFunctionManager) AppContext.getBean("matrimonyFunctionManager");
    private static final String userName = AppContext.getSystemProperty("oa.userName");
    private static final String password = AppContext.getSystemProperty("oa.password");

    private CAP4FormManager cap4FormManager = (CAP4FormManager) AppContext.getBean("cap4FormManager");
    private OrgManager orgManager = (OrgManager) AppContext.getBean("orgManager");

    /**
     * 处理自定义发起表单协同的接口方法
     *
     * @param param 包含所有请求参数的映射对象
     * @return 响应对象，包含处理结果
     */
    @POST
    @Path("send/form/collaboration")
    public Response sendFormCollaboration(Map<String, Object> param) {
        // 将参数对象转换为JSON字符串并记录日志
        String params = JSON.toJSONString(param);
        log.info("第三方系统调用自定义发起表单协同接口推送数据json报文:" + params);
        // 初始化变量
        String formCode = "";
        String formName = "";
        String returnMsg = "";
        try {
            // 转换请求参数为JSONObject以便后续处理
            JSONObject jsonObject = new JSONObject(param);

            // 获取并校验模板编码
            String templateCode = "";
            if (jsonObject.containsKey("templateCode")) {
                templateCode = StrKit.str(jsonObject.get("templateCode")).trim();
            }
            if ("".equals(templateCode)) {
                // 如果模板编码为空，返回错误信息
                String result = MessageKit.msg("E", "dataId", "", "templateCode 流程模版编码不能为空!");
                LogKit.addLog(formCode, "自定义发起表单协同", params, result);
                return ok(result);
            }

            // 根据模板编码获取表单信息
            FormBean formBean = cap4FormManager.getFormByFormCode(templateCode);
            if (formBean == null) {
                // 如果表单信息不存在，返回错误信息
                String result = MessageKit.msg("E", "dataId", "", "templateCode 流程模版编码[" + templateCode + "]不存在!");
                LogKit.addLog(formCode, "自定义发起表单协同", params, result);
                return ok(result);
            }

            // 设置表单名称
            formName = formBean.getFormName() + "-发起协同流程";

            // 获取请求对象并校验认证信息
            HttpServletRequest request = AppContext.getRawRequest();
            String authorization = StrKit.str(request.getHeader("Authorization"));
            if ("".equals(authorization)) {
                String result = MessageKit.msg("E", "dataId", "", "认证信息不能为空,认证方式为 Basic Auth");
                LogKit.addLog(formCode, formName, params, result);
                return ok(result);
            }

            // 校验认证信息是否正确
            String sapAccount = userName + ":" + password;
            String authorization_new = "Basic " + new BASE64Encoder().encode(sapAccount.getBytes());
            if (!authorization.equals(authorization_new)) {
                String result = MessageKit.msg("E", "dataId", "", "认证失败,账号或密码错误!");
                LogKit.addLog(formCode, formName, params, result);
                return ok(result);
            }
            V3xOrgMember v3xOrgMember = null;
            if (jsonObject.containsKey("mainData")) {
                JSONObject mainData = jsonObject.getJSONObject("mainData");
                v3xOrgMember = matrimonyFunctionManager.getOrgMember(templateCode, mainData, formBean);
            }

            // 获取并校验发起人工号
//            String senderCode = "";
//            if (jsonObject.containsKey("senderCode")) {
//                senderCode = StrKit.str(jsonObject.get("senderCode")).trim();
//            }
//            if ("".equals(senderCode)) {
//                String result = MessageKit.msg("E", "dataId", "", "senderCode 发起人工号不能为空值!");
//                LogKit.addLog(formCode, formName, params, result);
//                return ok(result);
//            }
//
//            // 校验发起人在OA系统中是否存在
//            List<V3xOrgMember> orgMemberList = orgManager.getMemberListWithOuterByMobile(senderCode, null);
////            List<V3xOrgEntity> orgMemberList = orgManager.getEntityList(V3xOrgMember.class.getSimpleName(), "code", senderCode, null, false, true);
//            if (orgMemberList.isEmpty()) {
//                String result = MessageKit.msg("E", "dataId", "", "senderCode 根据手机号[" + senderCode + "]在系统中未找到对应账号或手机号维护有误!");
//                LogKit.addLog(formCode, formName, params, result);
//                return ok(result);
//            }
//            V3xOrgMember v3xOrgMember = (V3xOrgMember) orgMemberList.get(0);
            User user_new = UserUtil.build(v3xOrgMember, "", null);
            if (user_new != null) {
                UserUtil.setCurrentUser(user_new);
            }
            // 准备请求头并获取token
            Map<String, Object> headers = new HashMap<String, Object>();
            String tokenId = HttpKit.getToken(v3xOrgMember.getLoginName(), tokenUrl);

            // 构建请求数据
            Map<String, Object> map = new HashMap<String, Object>();
            Map<String, Object> formDataMap = new HashMap<String, Object>();
            map.put("appName", "collaboration");
            formDataMap.put("draft", "0");
            formDataMap.put("templateCode", templateCode);

            Map<String, Object> dataMap = new HashMap<String, Object>();
            String serialNumber = "";
            String image_sub_reference = "";
            String imageAttachments = "";
            // 处理主表数据
            if (jsonObject.containsKey("mainData")) {
                JSONObject mainData = jsonObject.getJSONObject("mainData");
                List<FormFieldBean> mainFieldBeans = formBean.getMasterTableBean().getFields();
                String mainTableName = formBean.getMasterTableBean().getTableName();
                Map<String, Object> mainDataMap = JsonKit.mainData(mainData, mainFieldBeans);
                if (mainDataMap.containsKey("thirdAttachments")) {
                    dataMap.put("thirdAttachments", mainDataMap.get("thirdAttachments"));
                    mainDataMap.remove("thirdAttachments");
                }
                if (mainDataMap.containsKey("imageAttachments")) {
                    imageAttachments = StrKit.str(mainDataMap.get("imageAttachments"));
                    mainDataMap.remove("imageAttachments");
                }
                if (mainDataMap.containsKey("image_sub_reference")) {
                    image_sub_reference = StrKit.str(mainDataMap.get("image_sub_reference"));
                    mainDataMap.remove("image_sub_reference");
                }
                if (mainDataMap.containsKey("serialNumber")) {
                    serialNumber = StrKit.str(mainDataMap.get("serialNumber"));
                    mainDataMap.remove("serialNumber");
                }
                dataMap.put(mainTableName, mainDataMap);
            }

            // 处理子表数据
            if (jsonObject.containsKey("detailData")) {
                JSONArray subJsonArray = jsonObject.getJSONArray("detailData");
                if (!subJsonArray.isEmpty()) {
                    Map<String, List<Map<String, Object>>> subDataMap = JsonKit.subData(subJsonArray, formBean);
                    if (!subDataMap.isEmpty()) {
                        for (String key : subDataMap.keySet()) {
                            dataMap.put(key, subDataMap.get(key));
                        }
                    }
                }
            }

            // 组装最终请求数据
            formDataMap.put("data", dataMap);
            map.put("data", formDataMap);
            String dataJson = JSON.toJSONString(map);
            log.info("发送协同流程json:" + dataJson);

            // 设置请求头并发送请求
            headers.put("token", tokenId);
            String result = HttpKit.post(bpmUrl, headers, dataJson);
            returnMsg = MessageKit.bpmMessage(result, serialNumber);
            JSONObject resultObj = JSONObject.parseObject(returnMsg);
            String colSummaryId = StrKit.str(resultObj.get("dataId"));
            if (!"".equals(colSummaryId) && !"".equals(imageAttachments) && !"".equals(image_sub_reference)) {
                String[] fileUrls = imageAttachments.split(",");
                for (String fileId : fileUrls) {
                    FileKit.addAttachment(Long.parseLong(fileId), Long.parseLong(colSummaryId), Long.parseLong(image_sub_reference));
                }
            }
            LogKit.addLog(formCode, formName, params, returnMsg);
            return ok(returnMsg);
        } catch (Exception e) {
            // 异常处理
            log.error("自定义发起表单协同接口异常信息:", e);
            String result = MessageKit.msg("E", "dataId", "", e.getMessage());
            LogKit.addLog(formCode, formName, params, result);
            return ok(result);
        }
    }
}